package 接口.基础;
class Person implements Cloneable{
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person(int age) {
        this.age = age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

class Fruit implements Cloneable{
    int number;

    public Fruit(int number) {
        this.number = number;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "number= "+number;
    }
}
class Apple implements Cloneable{
    int size;
    Fruit fruit;

    public Apple(int size, Fruit fruit) {
        this.size = size;
        this.fruit = fruit;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Apple stm = (Apple) super.clone();
//        stm.fruit =(Fruit)fruit.clone();
        stm.fruit = (Fruit) this.fruit.clone();
        return stm;

    }

    @Override
    public String toString() {
        return "Apple{" +
                "size=" + size +
                " , " + fruit +
                '}';
    }
}
public class Clone_1 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("zhangsan",13);
        Person person2 = (Person) person1.clone();
        //clone()使用有4个问题；
        // 1.访问限定符，object类中clone方法用protect修饰，不能直接调用，需要子类重写
        //2.throws CloneNotSupportedException用于异常处理的一种声明方式:不支持克隆
        //3.向下转型，重写的返回值是一个object类型，要转为Personal类型
        //4.实现Cloneable 接口（标记接口或者空接口），本身没有定义任何方法，作用是告诉 Java 虚拟机这个类的对象是可以被克隆的。

        //浅拷贝：对于基本数据类型，会直接复制其值；而对于引用数据类型，仅仅复制对象的引用
        System.out.println(person1);
        System.out.println(person2);
        System.out.println("==========");
        person2.name = "lisi";
        person2.age = 18;
        System.out.println(person1);
        System.out.println(person2);
//    String 是不可变类。这意味着一旦一个 String 对象被创建，它的内容就不能再被更改。
//    当你对一个 String 变量进行赋值操作时，实际上是让该变量指向了一个新的 String 对象。

        //深拷贝：对于原对象中的所有属性，无论其是基本数据类型还是引用数据类型，都会创建一个完全独立的副本
        System.out.println("================");
        Fruit fruit = new Fruit(15);
        Apple apple1 = new Apple(12,fruit);
        Apple apple2 =(Apple) apple1.clone();
        System.out.println(apple1);
        System.out.println(apple2);
        System.out.println("=========");
        apple2.fruit.number = 11;
        System.out.println(apple1);
        System.out.println(apple2);
    }
}
//Person{name='zhangsan', age=13}
//Person{name='zhangsan', age=13}
//==========
//Person{name='zhangsan', age=13}
//Person{name='zhangsan', age=18}